{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 1. 创建张量"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "import torch"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "tensor([ 1,  2,  3,  4,  5,  6,  7,  8,  9, 10])\n",
      "torch.Size([10])\n",
      "<class 'torch.Tensor'>\n"
     ]
    }
   ],
   "source": [
    "# 创建张量\n",
    "x = torch.arange(1,11)\n",
    "print(x)\n",
    "print(x.shape)\n",
    "print(type(x))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "tensor([[ 1,  2,  3,  4],\n",
       "        [ 5,  6,  7,  8],\n",
       "        [ 9, 10, 11, 12]])"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 使用特定的值创建张量\n",
    "x = torch.tensor([[1,2,3,4],[5,6,7,8],[9,10,11,12]])\n",
    "x"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 2. 元素级别的运算"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(tensor([1.6849, 2.5263, 3.2807, 4.2003]),\n",
       " tensor([0.3151, 1.4737, 2.7193, 3.7997]),\n",
       " tensor([0.6849, 1.0525, 0.8421, 0.8013]),\n",
       " tensor([ 1.4600,  3.8004, 10.6877, 19.9685]),\n",
       " tensor([1.0000, 1.4402, 1.3612, 1.3201]))"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 元素级别的运算\n",
    "x = torch.arange(1,5)\n",
    "y = torch.rand(size=(4,))\n",
    "\n",
    "# 矩阵对应元素+,-,*,/,^\n",
    "x+y, x-y, x*y, x/y, x**y"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 3. 张量拼接"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(tensor([[ 1,  2,  3,  4],\n",
       "         [ 5,  6,  7,  8],\n",
       "         [ 9, 10, 11, 12]]),\n",
       " tensor([[ 1,  3,  9,  2],\n",
       "         [ 2,  2,  3, 11],\n",
       "         [ 6,  9, 12,  1]]))"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x = torch.arange(1,13).reshape(3,4)\n",
    "y = torch.randint(low=1,high=13,size=(3,4))\n",
    "x,y"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "tensor([[ 1,  2,  3,  4],\n",
       "        [ 5,  6,  7,  8],\n",
       "        [ 9, 10, 11, 12],\n",
       "        [ 1,  3,  9,  2],\n",
       "        [ 2,  2,  3, 11],\n",
       "        [ 6,  9, 12,  1]])"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "torch.cat((x,y),dim=0)  # dim=0:按行进行拼接"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "tensor([[ 1,  2,  3,  4,  1,  3,  9,  2],\n",
       "        [ 5,  6,  7,  8,  2,  2,  3, 11],\n",
       "        [ 9, 10, 11, 12,  6,  9, 12,  1]])"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "torch.cat((x,y),dim=1) # dim=1:按列进行拼接"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<img src=\"https://zyc-learning-1309954661.cos.ap-nanjing.myqcloud.com/machine-learning-pic/2020081016403863.png\" alt=\"二维矩阵\" style=\"zoom: 50%;\" />"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 3. 张量中的数据统计"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(tensor([[ 1,  2,  3,  4],\n",
       "         [ 5,  6,  7,  8],\n",
       "         [ 9, 10, 11, 12]]),\n",
       " tensor(78),\n",
       " tensor(12),\n",
       " tensor(1))"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x = torch.arange(1,13).reshape(3,4)\n",
    "x, x.sum(), x.max(), x.min()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 4. 张量运算中的广播机制"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(tensor([[0],\n",
       "         [1],\n",
       "         [2]]),\n",
       " tensor([[0, 1]]),\n",
       " tensor([[0, 1],\n",
       "         [1, 2],\n",
       "         [2, 3]]))"
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x = torch.arange(3).reshape(3,1)\n",
    "y = torch.arange(2).reshape(1,2)\n",
    "x,y,x+y"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "![image-20240410155253290](https://zyc-learning-1309954661.cos.ap-nanjing.myqcloud.com/machine-learning-pic/image-20240410155253290.png)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 5. 元素访问"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(tensor([[ 1,  2,  3,  4],\n",
       "         [ 5,  6,  7,  8],\n",
       "         [ 9, 10, 11, 12]]),\n",
       " tensor([ 9, 10, 11, 12]),\n",
       " tensor([ 4,  8, 12]),\n",
       " tensor([[ 1,  2,  3,  4],\n",
       "         [ 9, 10, 11, 12]]))"
      ]
     },
     "execution_count": 29,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x = torch.arange(1,13).reshape(3,4)\n",
    "x, \\\n",
    "x[-1,:], \\\n",
    "x[:,-1], \\\n",
    "x[0:3:2,:]  # 0~2行，每隔两行访问"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 6. 元素修改"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "tensor([[0., 0., 0., 0., 0.],\n",
       "        [0., 1., 1., 0., 0.],\n",
       "        [0., 0., 0., 0., 0.],\n",
       "        [0., 0., 0., 0., 0.],\n",
       "        [0., 0., 0., 0., 0.]])"
      ]
     },
     "execution_count": 33,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x = torch.zeros(size=(5,5))\n",
    "x[1:2, 1:3]=1   # 赋值可以直接改变值\n",
    "x"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 7. 运算前后变量在内存中的变化"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 37,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "previous: 2379028033072\n",
      "current: 2379028030032\n"
     ]
    }
   ],
   "source": [
    "x = torch.arange(10)\n",
    "print('previous:', id(x))\n",
    "x = x + 1\n",
    "print('current:', id(x))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "上述代码表示：执行`x = x + 1`操作后，`x`在内存中以及不是原来的`x`了"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 38,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "previous: 2379028085184\n",
      "current: 2379028085184\n"
     ]
    }
   ],
   "source": [
    "x = torch.arange(10)\n",
    "print('previous:', id(x))\n",
    "x += 1\n",
    "print('current:', id(x))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "但是，使用`x += 1`，`x`在内存中的位置不变"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 8. torch和numpy的转化"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 40,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 45,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(tensor([[31,  4,  1, 31],\n",
       "         [13, 31,  4,  1],\n",
       "         [ 4,  2, 56,  1]], dtype=torch.int32),\n",
       " torch.Tensor)"
      ]
     },
     "execution_count": 45,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 用numpy数组创建tensor\n",
    "x = np.array([[31,4,1,31],[13,31,4,1],[4,2,56,1]])\n",
    "tensor = torch.tensor(x)\n",
    "tensor, type(tensor)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 46,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(array([[31,  4,  1, 31],\n",
       "        [13, 31,  4,  1],\n",
       "        [ 4,  2, 56,  1]], dtype=int64),\n",
       " numpy.ndarray)"
      ]
     },
     "execution_count": 46,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 用tensor获取对应的numpy数组\n",
    "x = torch.tensor([[31,4,1,31],[13,31,4,1],[4,2,56,1]])\n",
    "ndarray = x.numpy()\n",
    "ndarray, type(ndarray)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "torch",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.10.14"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
